package com.baturu.vin.benz.service.impl.supers;

import com.baturu.vin.base.constant.MySQLVariables;
import com.baturu.vin.benz.dal.dao.BenzEPCPartsInfoDAO;
import com.baturu.vin.benz.dal.dao.BenzPartsMappingDAO;
import com.baturu.vin.benz.dto.*;
import com.baturu.vin.benz.service.impl.BenzImageService;
import com.baturu.vin.benz.service.impl.util.BenzI18nService;
import com.baturu.vin.kit.StreamKit;
import com.google.common.collect.Sets;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * BenzSuperPartsService
 *
 * @author majianming
 * @date 2019-04-19 17:52
 */
@Service
public class BenzSuperPartsService {

    @Autowired
    private BenzEPCPartsInfoDAO benzEPCPartsInfoDAO;
    @Autowired
    private BenzPartsMappingDAO benzPartsMappingDAO;

    @Autowired
    private BenzImageService imageService;

    @Autowired
    private BenzI18nService benzI18nService;

    @Autowired
    private BenzSuperPartsFilterService benzSuperPartsFilterService;


    List<BenzSuperPartsInfoDTO> queryPartsInfoByPartsCode(String partsCode, BenzSuperCarInfoDTO superCarInfoDTO) {
        if (StringUtils.isBlank(partsCode)) {
            return Collections.emptyList();
        }

        BenzSuperCarConfigurationDTO benzConfig = superCarInfoDTO.getBenzSuperCarConfigurationDTO();
        HashSet<String> selectNos = Sets.newHashSet(benzConfig.getCarNo(), benzConfig.getEngineNo(), benzConfig.getTransmissionNo());


        List<BenzSuperPartsInfoDTO> benzSuperPartsInfoDTOS =
                benzEPCPartsInfoDAO.queryPartsInfoByCar(selectNos,
                        null, null, partsCode);
        if (CollectionUtils.isEmpty(benzSuperPartsInfoDTOS)) {
            return Collections.emptyList();
        }


        List<BenzSuperPartsInfoDTO> benzSuperPartsInfoDTOSAfterFilter = benzSuperPartsFilterService.filterParts(benzSuperPartsInfoDTOS, superCarInfoDTO, Sets.newHashSet(benzConfig.getCarNo(), benzConfig.getEngineNo(), benzConfig.getTransmissionNo()));
        if (CollectionUtils.isEmpty(benzSuperPartsInfoDTOSAfterFilter)) {
            return Collections.emptyList();
        }
        List<BenzSuperPartsInfoDTO> benzSuperPartsInfoDTOSAfterImages = benzSuperPartsInfoDTOSAfterFilter.stream().map(p -> BenzSuperSubGroupDTO.builder().catNum(p.getCatNum()).mainGroupNo(p.getGroup()).subGroupNo(p.getSubGroup()).build()).flatMap(subGroupDTO -> imageService.setPartsImages(benzSuperPartsInfoDTOSAfterFilter, subGroupDTO).stream()).collect(Collectors.toList());


        Set<String> btrPartsCodes = benzSuperPartsInfoDTOSAfterImages.stream().map(BenzSuperPartsInfoDTO::getBtrPartsCode).filter(StringUtils::isNotBlank).collect(Collectors.toSet());

        Map<String, String> partsCodeMap = StreamKit.partitionStream(btrPartsCodes, MySQLVariables.EQ_RANGE_INDEX_DIVE_LIMIT).flatMap(
                l -> benzPartsMappingDAO.getByPartsCode(l).stream()
        ).collect(Collectors.toMap(
                BenzPartsMappingDTO::getPartsCode,
                l -> Sets.newHashSet(l.getBtrPartsName()),
                (a, b) -> {
                    a.addAll(b);
                    return b;
                }
        )).entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, l -> String.join(",", l.getValue())));


        Set<String> descIndexSet = benzSuperPartsInfoDTOSAfterFilter.stream().map(BenzSuperPartsInfoDTO::getDescIdx).collect(Collectors.toSet());
        if (CollectionUtils.isEmpty(descIndexSet)) {
            return Collections.emptyList();
        }
        String landCode = benzI18nService.getBenzLangEnum().getLandCode();
        Map<String, List<BenzSuperDescDTO>> partsDescMap = benzEPCPartsInfoDAO.queryPartEpcDesc(descIndexSet, landCode).stream().collect(Collectors.groupingBy(BenzSuperDescDTO::getDescIndex));

        Set<String> nounIdx = benzSuperPartsInfoDTOS.stream().map(BenzSuperPartsInfoDTO::getNounIdx).collect(Collectors.toSet());
        Map<String, String> nounNameName = benzEPCPartsInfoDAO.findNounByIdx(nounIdx, landCode).stream().collect(Collectors.toMap(BenzEPCPartsNameDTO::getNounIdx, BenzEPCPartsNameDTO::getNoun));

        return benzSuperPartsInfoDTOSAfterFilter.stream().peek(l -> {
            String descIndex = l.getDescIdx();
            List<BenzSuperDescDTO> benzSuperDescDTOS = partsDescMap.get(descIndex);
            if (CollectionUtils.isNotEmpty(benzSuperDescDTOS)) {
                l.setDesc(benzSuperDescDTOS.get(0).getDesc());
            }
            l.setBtrPartsName(partsCodeMap.get(l.getBtrPartsCode()));
            l.setNounName(nounNameName.get(l.getNounIdx()));
            l.setQty(StringUtils.substring(l.getQty(), 0, 3));
        }).collect(Collectors.toList());
    }


    List<BenzSuperPartsInfoDTO> queryPartsInfo(BenzSuperSubGroupDTO subGroupDTO, BenzSuperCarInfoDTO superCarInfoDTO) {
        List<BenzImagesDTO> benzImagesDTOS = subGroupDTO.getBenzImagesDTOS();
        if (CollectionUtils.isEmpty(benzImagesDTOS)) {
            return Collections.emptyList();
        }

        String imageCode = benzImagesDTOS.get(0).getImageCode();
        if (StringUtils.isBlank(imageCode)) {
            return Collections.emptyList();
        }

        List<BenzSuperPartsInfoDTO> benzSuperPartsInfoDTOS = benzEPCPartsInfoDAO.queryPartsInfoByCar(Sets.newHashSet(subGroupDTO.getBaseCode()), subGroupDTO.getMainGroupNo(), subGroupDTO.getSubGroupNo(), null);
        if (CollectionUtils.isEmpty(benzSuperPartsInfoDTOS)) {
            return Collections.emptyList();
        }


        List<BenzSuperPartsInfoDTO> benzSuperPartsInfoDTOSAfterFilter = benzSuperPartsFilterService.filterParts(benzSuperPartsInfoDTOS, superCarInfoDTO, Sets.newHashSet(subGroupDTO.getBaseCode()));

        Set<String> btrPartsCodes = benzSuperPartsInfoDTOSAfterFilter.stream().map(BenzSuperPartsInfoDTO::getBtrPartsCode).filter(StringUtils::isNotBlank).collect(Collectors.toSet());
        List<BenzSuperPartsInfoDTO> benzSuperPartsInfoDTOSAfterImages = imageService.setPartsImages(benzSuperPartsInfoDTOSAfterFilter, subGroupDTO);

        benzSuperPartsInfoDTOSAfterImages = benzSuperPartsInfoDTOSAfterImages.stream().filter(l -> StringUtils.equals(imageCode, l.getImageCode())).collect(Collectors.toList());


        Map<String, String> partsCodeMap = StreamKit.partitionStream(btrPartsCodes, MySQLVariables.EQ_RANGE_INDEX_DIVE_LIMIT).flatMap(
                l -> benzPartsMappingDAO.getByPartsCode(l).stream()
        ).collect(Collectors.toMap(
                BenzPartsMappingDTO::getPartsCode,
                l -> Sets.newHashSet(l.getBtrPartsName()),
                (a, b) -> {
                    a.addAll(b);
                    return a;
                }
        )).entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, l -> String.join(",", l.getValue())));
        String landCode = benzI18nService.getBenzLangEnum().getLandCode();
        Set<String> nounIdx = benzSuperPartsInfoDTOS.stream().map(BenzSuperPartsInfoDTO::getNounIdx).collect(Collectors.toSet());
        Map<String, String> nounNameName = benzEPCPartsInfoDAO.findNounByIdx(nounIdx, landCode).stream().collect(Collectors.toMap(BenzEPCPartsNameDTO::getNounIdx, BenzEPCPartsNameDTO::getNoun));


        Set<String> descIndexSet = benzSuperPartsInfoDTOSAfterFilter.stream().map(BenzSuperPartsInfoDTO::getDescIdx).collect(Collectors.toSet());
        if (CollectionUtils.isEmpty(descIndexSet)) {
            return Collections.emptyList();
        }
        Map<String, List<BenzSuperDescDTO>> partsDescMap = benzEPCPartsInfoDAO.queryPartEpcDesc(descIndexSet, landCode).stream().collect(Collectors.groupingBy(BenzSuperDescDTO::getDescIndex));


        return benzSuperPartsInfoDTOSAfterImages.stream().peek(l -> {
            String descIndex = l.getDescIdx();
            List<BenzSuperDescDTO> benzSuperDescDTOS = partsDescMap.get(descIndex);
            if (CollectionUtils.isNotEmpty(benzSuperDescDTOS)) {
                l.setDesc(benzSuperDescDTOS.get(0).getDesc());
            }
            l.setBtrPartsName(partsCodeMap.get(l.getBtrPartsCode()));
            l.setNounName(nounNameName.get(l.getNounIdx()));
            l.setQty(StringUtils.substring(l.getQty(), 0, 3));
        }).collect(Collectors.toList());
    }
}
